package com.yulian.service;

import java.util.Set;

import com.yulian.repository.CommonRepositoryImpl;

import com.yulian.web_api.report.*;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.Log4JLoggerFactory;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.User;
import io.vertx.ext.web.FileUpload;
import io.vertx.pgclient.PgPool;
import io.vertx.sqlclient.SqlConnection;
/**
 * 
 * @author yudayong
 *
 */
public class BatchImport {
	final InternalLogger logger = Log4JLoggerFactory.getInstance(BatchImport.class);
	CommonRepositoryImpl commonRepository = new CommonRepositoryImpl();
	/**
	 * 获取数据库链接
	 * @param client
	 * @return
	 */
	public Future<SqlConnection> getCon(PgPool client){
		Promise<SqlConnection> promise = Promise.promise();
		// Get a connection from the pool
		client.getConnection(ar1 -> {
			if (ar1.succeeded()) { 
				//Obtain our connection
				SqlConnection conn = ar1.result();
				promise.complete(conn);
			} else { 
				//Vert.x帮我们捕获异常后，我们只需要做接下来的处理即可，比如写日志
				logger.info("连接数据库错误信息: "+ar1.cause().toString());
		        promise.fail(ar1.cause());  //这里就相当于继续向上抛出异常，用Promise来向上抛异常 
			}
		});
		return promise.future();
	}
	
	/**
     *  在这个 event-loop-verticle 里面对上传文件重新命名 ，当excel里面数据太多的时候，需要让另一个 workVerticle 来处理
     * @param vertx
     * @param eventBus
     * @param config
     * @param files
     * @param user
     * @return
     */
	public Future<JsonObject> handleUploadExcelFile(Vertx vertx, EventBus eventBus, PgPool pool, JsonObject config, Set<FileUpload> files, String source_from,  User user) { 
		Promise<JsonObject> promise = Promise.promise();   
  		JsonObject responseJSObj = new JsonObject(); 
  		if(files.size() == 0) { 
  			responseJSObj.put("code", -1).put("msg", "上传文件错误,数量为0");
  			promise.complete(responseJSObj); 
  		}else { 
  			//设一次只能上传一个excel文件
  	    	for(FileUpload f: files) { 
  				String uploadedFileName =  f.uploadedFileName();
  				logger.info("in file handler, uploadedFileName: {} ", f.uploadedFileName());
  			 
  				//获取文件扩展名
  				String file_ext = f.fileName().substring(f.fileName().lastIndexOf("."), f.fileName().length());  
  				String file_name = "webroot/upload/test" +  file_ext; 
  				logger.info("in file handle, file_name: {} ", file_name);
  				//先异步删除已经存在的文件，然后再把新上传的文件移动到指定路径下
  				vertx.fileSystem().delete(file_name,res0->{
  					vertx.fileSystem().move(uploadedFileName, file_name, res->{
  						if(res.succeeded()) {   
  							/**
  							 * 方法1，发送消息到事件总线，由worker verticle进行处理
  							 */
//  							JsonObject data = new JsonObject();
//  							data.put("file_name", file_name).put("source_from", source_from); 
//  							//使用传送事件到event_bus到通用sendMessageToEventBus, 需要有地址，数据data；
//  							CommonToEventBus commonToEventBus = new CommonToEventBus();
//  							String address_handle_excel = "handle_upload_excel"; //config.getString("EVENT_BUS_KEY_PREFIX") +"."+config.getString("KEY_HANDLE_EXCEL");
//  							commonToEventBus.sendMessageToEventBus(eventBus, address_handle_excel,  data)
//  							.onComplete( ar2->{  
//  								if (ar2.succeeded()) { 
//  									responseJSObj.put("msg", ar2.result().toString());
//  									promise.complete(responseJSObj); 
//  								} else {
//  									ar2.cause().printStackTrace();
//  									responseJSObj.put("code", -1);
//  									responseJSObj.put("msg", responseJSObj.getString("msg")+"; 发送处理excel文件消息时发生错误"+ar2.cause().getMessage());   
//  									promise.complete(responseJSObj); 
//  								} 
//  							}); 
  							/**
  							 * 方法2，直接调用服务类进行处理
  							 */
  							
  							switch(source_from) {
  							case "initial_batch_detail":
								HandleInitialBatchDetial handleInitialBatchDetial = new HandleInitialBatchDetial();
								handleInitialBatchDetial.handleExcelFile(vertx, pool,config,   file_name,user )
  								.onSuccess(result -> {                                                     
  									logger.info("批量导入期初库存批次明细成功");
//  									responseJSObj.put("msg", result.getString("msg"));
  									promise.complete(result);
  								})
  								.onFailure(err ->{ 
  									logger.info("批量导入期初库存批次明细失败");
  									promise.complete(responseJSObj);  
  								});  

  								break;
							case "sales_return_warehouse_detail":
								HandleSalesReturnWarehouseDetail handleSalesReturnWarehouseDetail = new HandleSalesReturnWarehouseDetail();
								handleSalesReturnWarehouseDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量销售退库入库单导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量销售退库入库单导入失败");
												promise.complete(responseJSObj);
											});

									break;
							case "shift_delivery_plan_completion_detail":
								HandleShiftDeliveryPlanCompletionDetail handleShiftDeliveryPlanCompletionDetail = new HandleShiftDeliveryPlanCompletionDetail();
								handleShiftDeliveryPlanCompletionDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("车次配送计划完工单明细导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("车次配送计划完工单明细导入失败");
												promise.complete(responseJSObj);
											});

									break;
							case "pickup_completion_detail":
								HandlePickupCompletionDetail handlePickupCompletionDetail = new HandlePickupCompletionDetail();
								handlePickupCompletionDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量自提完工单明细导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量自提完工单明细导入失败");
												promise.complete(responseJSObj);
											});

									break;
							case "purchase_return_detail":
									HandlePurchaseReturnDetail handlePurchaseReturnDetail = new HandlePurchaseReturnDetail();
									handlePurchaseReturnDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量采购退货单导入导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量采购退货单导入失败");
												promise.complete(responseJSObj);
											});

									break;
							case "good_damage_supplier_subsidy_detail":
								HandleGoodDamageSupplierSubsidyDetail handleGoodDamageSupplierSubsidyDetail = new HandleGoodDamageSupplierSubsidyDetail();
								handleGoodDamageSupplierSubsidyDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量商品折损供应商补贴单明细导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量商品折损供应商补贴单明细导入失败");
												promise.complete(responseJSObj);
											});

									break;
							case "good_indoor_subsidy_detail":
								HandleGoodIndoorSubsidyDetail handleGoodIndoorSubsidyDetail = new HandleGoodIndoorSubsidyDetail();
								handleGoodIndoorSubsidyDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量商品内部赔偿单明细导入\n成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量商品内部赔偿单明细导入\n失败");
												promise.complete(responseJSObj);
											});

									break;
							case "sales_complaints_subsidy_detail":
								HandleSalesComplaintsSubsidyDetail handleSalesComplaintsSubsidyDetail = new HandleSalesComplaintsSubsidyDetail();
								handleSalesComplaintsSubsidyDetail.handleExcelFile(vertx, pool,config,   file_name )
											.onSuccess(result -> {
												logger.info("批量销售投诉赔偿单明细导入成功");
//												responseJSObj.put("msg", result.getString("msg"));
												promise.complete(result);
											})
											.onFailure(err ->{
												logger.info("批量销售投诉赔偿单明细导入失败");
												promise.complete(responseJSObj);
											});

									break;
  							} 
  							
  						}else {
  							responseJSObj.put("msg", "上传文件失败,原因:"+res.cause().getMessage()); 
  		    				promise.complete(responseJSObj); 
  						} 
  					});
  				}); 
  			}
  		} 
		return promise.future();
	} 

}
 
